
using Common.UGUI.Base;
using Common.UGUI.Base.Data;
using Common.UGUI.View;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// 一个不错的结构，暂时没用Aync,Win管理等没用上
/// </summary>
namespace Common.UGUI {

    public class UGUIModule //: AsyncModule<UGUIModule> 
    {

        #region 域

        /// <summary>
        /// 从UGUIBaseData中获取的x轴逻辑分辨率
        /// </summary>
        public static float ResolutionX { get; private set; }

        /// <summary>
        /// 从UGUIBaseData中获取的y轴逻辑分辨率
        /// </summary>
        public static float ResolutionY { get; private set; }

        /// <summary>
        /// 全局UI标准数据
        /// </summary>
        public UGUIBaseData UGUIBaseData {
            get{
                return _uguiBaseData;
            }
        }

        protected List<string> _baseCanvasList = new List<string>();

        protected UGUIRoot _uguiRoot = null;
        protected EventSystem _eventSystem = null;
        protected StandaloneInputModule _inputModule = null;

        /// <summary>
        /// 是否Unity启动后第一次加载
        /// </summary>
        protected static bool _IfFirstTimeInitedSinceUnityPlayed = true;

        private UGUIBaseData _uguiBaseData = null;

        #endregion

        #region 覆盖Module

        //protected override bool OnInit() {

        //    if (!InitUGUIResPath()) {

        //        return false;
        //    }

        //    InitUGUIDatas();

        //    if (_baseCanvasList.Count == 0) {
        //        Debug.LogWarning("<color=#ff0000>UGUIModule init with empty canvas list, may be you should call SetCanvasList firstly.");
        //    }

        //    CheckUGUIFramework();

        //    return true;
        //}

        //protected override void OnInitedUpdate() {

        //}

        //protected override void OnActivatedUpdate() {

        //}

        //protected override bool OnPause() {
        //    return true;
        //}

        //protected override bool OnResume() {
        //    return true;
        //}

        //protected override bool OnRelease() {
        //    return true;
        //}

        #endregion

        #region 接口

        #endregion

        #region 数据初始化

        private bool InitUGUIResPath() {

            string uguiDataBundlePath = UGUIManager.UIRootBundlePath + UGUIBaseData.BundlePath;

            //GameObject uguiResPathObj = AssetBundleManager.Instance.LoadBaseAsset<GameObject>(uguiDataBundlePath, UGUIBaseData.PrefabName, null);
            GameObject uguiResPathObj = null;
            if (uguiResPathObj != null) {

                _uguiBaseData = uguiResPathObj.GetComponent<UGUIBaseData>();

                if (_uguiBaseData == null) {

                    Debug.LogError("UGUIModule init failed: loaded UGUIBaseData gameObject by path : " + uguiDataBundlePath + UGUIBaseData.PrefabName +  " has no UGUIBaseData component.");

                    return false;
                }

                ResolutionX = _uguiBaseData.ResolutionX;
                ResolutionY = _uguiBaseData.ResolutionY;

                return true;

            } else {

                Debug.LogError("UGUIModule init failed: load UGUIBaseData gameObject by path : " + uguiDataBundlePath + UGUIBaseData.PrefabName + " failed.");

                return false;
            }
        }

        private void InitUGUIDatas() {

            _uguiBaseData.RefreshBundleDictByData();

            _baseCanvasList = _uguiBaseData.BaseCanvasList;
        }

        #endregion

        #region 修复画布层级

        private static List<GameObject> _canvas2Delete = new List<GameObject>();
        private static HashSet<string> _canvasSet = new HashSet<string>();

        private void CheckAndFixUGUICanvas(string name, GameObject uguiObj) {

            UGUICanvas uguiCanvas = uguiObj.GetComponent<UGUICanvas>();

            if (uguiCanvas == null) {

                // 清除旧的无用UGUIView
                GameObject.Destroy(uguiObj.GetComponent<UGUIView>());

                uguiCanvas = uguiObj.AddComponent<UGUICanvas>();

            }

            uguiCanvas.SetName(name);
            uguiCanvas.SetResolution((int)ResolutionX, (int)ResolutionY);
            uguiCanvas.SortGameObjectBySortingOrder();
        }

        private void Check2LoadUGUICanvas(string name, Action<bool> onLoaded) {

            Transform canvas = _uguiRoot.Transform.Find(name);

            if (canvas != null) {

                CheckAndFixUGUICanvas(name, canvas.gameObject);

                onLoaded(true);
            } else {

                string bundleName = UGUIBaseData.UIName2BundleDict[name];

                //UGUIManager.Instance.NewGameObjectByName<UGUICanvas>(bundleName, name, _uguiRoot,

                //    (uguiView) => {

                //        if (uguiView != null) {

                //            CheckAndFixUGUICanvas(name, uguiView.GameObject);
                //        }

                //        onLoaded(true);

                //    }, (uguiError) => {

                //        Debug.LogError("Check2LoadUGUICanvas NewGameObjectByName with bundle path " + bundleName + name + " error: " + uguiError.ToString());

                //        onLoaded(false);
                //    }
                //);
            }
        }

        /// <summary>
        /// 按照配置文件的层级检查和重置所有配置文件声明的画布
        /// </summary>
        public void CheckAndFixCanvases() {

            _canvas2Delete.Clear();

            _canvasSet.Clear();

            Transform uguiRootTrans = _uguiRoot.Transform;

            int childCount = uguiRootTrans.childCount;

            if (childCount - 1 > _baseCanvasList.Count) {

                Debug.LogError("UGUIRoot canvas's number is more than config.");
            }

            foreach (string canvasName in _baseCanvasList) {
                if (!_canvasSet.Contains(canvasName)) {
                    _canvasSet.Add(canvasName);
                } else {
                    Debug.LogError("UGUIRoot CheckCanvases input canvasList has conflict name: " + canvasName);
                }
            }

            Transform child = null;

            for (int i = 0; i < childCount; ++i) {

                child = uguiRootTrans.GetChild(i);

                if (child != null) {

                    if (string.Compare(child.name, "EventSystem") != 0) {

                        if (!_canvasSet.Contains(child.name)) {

                            _canvas2Delete.Add(child.gameObject);
                        }
                    }
                }
            }

            for (int i = 0; i < _canvas2Delete.Count; ++i) {
                // 需要立刻销毁
                GameObject.DestroyImmediate(_canvas2Delete[i]);
            }

            int loadedCount = 0;
            bool ifEverFailed = false;

            // 因为前面还在做子对象更新操作，所以最后这里才进行目标Canvas的挂载
            foreach (string canvasName in _baseCanvasList) {

                Check2LoadUGUICanvas(canvasName, (ifSucc)=> {

                    if (!ifSucc) {

                        ifEverFailed = true;
                    }

                    ++loadedCount;

                    if (loadedCount == _baseCanvasList.Count) {

                        //if (!ifEverFailed) {

                        //    _onInitFinished();

                        //    _onInitFinished = null;
                        //} else {

                        //    if (_onInitFailed != null) {

                        //        _onInitFailed();

                        //        _onInitFailed = null;
                        //    }

                        //    UGUIModule.Instance.Release();
                        //}
                    }
                });
            }
        }

        #endregion

        #region 主结构检查

        private void CheckEventSystem() {

            Transform eventSystemTrans = _uguiRoot.Transform.Find("EventSystem");
            if (eventSystemTrans == null) {
                eventSystemTrans = new GameObject("EventSystem").transform;
            }
            GameObject eventSystem = eventSystemTrans.gameObject;

            _eventSystem = eventSystem.GetComponent<EventSystem>();

            if (_eventSystem == null) {

                _eventSystem = eventSystem.AddComponent<EventSystem>();

                _eventSystem.sendNavigationEvents = true;

                _eventSystem.pixelDragThreshold = 5;
            }

            _inputModule = eventSystem.GetComponent<StandaloneInputModule>();

            if (_inputModule == null) {

                _inputModule = eventSystem.AddComponent<StandaloneInputModule>();

                _inputModule.horizontalAxis = "Horizontal";

                _inputModule.verticalAxis = "Vertical";

                _inputModule.submitButton = "Submit";

                _inputModule.cancelButton = "Cancel";

                _inputModule.inputActionsPerSecond = 10f;

                _inputModule.repeatDelay = 0.5f;

                _inputModule.forceModuleActive = false;
            }
        }

        private void CheckUGUIFramework() {

            GameObject uguiRootGO = GameObject.Find("UGUIRoot");

            if (uguiRootGO == null) {

                string bundleName = UGUIBaseData.UIName2BundleDict["UGUIRoot"];

                //UGUIManager.Instance.NewGameObjectByName<UGUIRoot>(bundleName, "UGUIRoot", null, (uguiView) => {

                //    _uguiRoot = uguiView as UGUIRoot;

                //    _uguiRoot.SetName("UGUIRoot");

                //    CheckEventSystem();

                //    CheckAndFixCanvases();

                //},(errorCode)=> {

                //    if(errorCode == LoadUIErrorCode.UGUIViewTypeNotRightError) {

                //        Debug.LogError("UGUIModule init with UGUIRoot failed! Prefab is wrong.");
                //    }

                //    UGUIModule.Instance.Release();

                //    if(_onInitFailed != null) {

                //        _onInitFailed();

                //        _onInitFailed = null;
                //    }
                //});

            } else {

                // 有可能预先在编辑器创建了UGUI
                if (_IfFirstTimeInitedSinceUnityPlayed) {

                    _uguiRoot = uguiRootGO.GetComponent<UGUIRoot>();

                    if (_uguiRoot == null) {

                        _uguiRoot = uguiRootGO.AddComponent<UGUIRoot>();
                    }

                    GameObject.DontDestroyOnLoad(uguiRootGO);

                    _IfFirstTimeInitedSinceUnityPlayed = false;
                }

                CheckEventSystem();

                CheckAndFixCanvases();
            }
        }

        #endregion
    }
}
